/*
 * @Author       : Zhao Lvhua zhaolh@linkcharging.com
 * @Date         : 2024-09-02 01:04:00
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:02:31
 * @FilePath     : \openchaoji-corelib\shared\src\OpenChaoJi_utility_transport_gbt27930_b_connect.c
 * @Description  :
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include "OpenChaoJi_utility_transport_gbt27930_b.h"
#include "OpenChaoJi_utility_transport_gbt27930_b_private.h"

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)


struct OpenChaoJi_gbt27930_b_canframe_cache * OpenChaoJi_transport_gbt27930_b_canframe_cache_new(void)
{
	struct OpenChaoJi_gbt27930_b_canframe_cache * gbt27930_b_canframe_cache = NULL;

	gbt27930_b_canframe_cache = (struct OpenChaoJi_gbt27930_b_canframe_cache *)OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_gbt27930_b_canframe_cache));
	return gbt27930_b_canframe_cache;
}

int16_t OpenChaoJi_transport_gbt27930_b_canframe_cache_free(struct OpenChaoJi_gbt27930_b_canframe_cache * canframe_cache)
{
	OpenChaoJi_os_free(canframe_cache);
	return 0;
}

int16_t  OpenChaoJi_transport_gbt27930_b_canframe_cache_init(struct OpenChaoJi_gbt27930_b_canframe_cache * canframe_cache)
{
	if (canframe_cache == NULL){
		LOG_CRIT("transport cache malloc fail");
		return -1;
	}

	canframe_cache->cnt = 0;
	memset(canframe_cache->pdu,0,sizeof(canframe_cache->pdu));

	return 0;
}

struct OpenChaoJi_gbt27930_b_urmcb * OpenChaoJi_transport_gbt27930_b_urm_new(void * param)
{
	struct OpenChaoJi_gbt27930_b_urmcb * gbt27930_b_urmcb = NULL;

	gbt27930_b_urmcb = (struct OpenChaoJi_gbt27930_b_urmcb *)OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_gbt27930_b_urmcb));
	if (gbt27930_b_urmcb == NULL)
	{
		LOG_CRIT("transport urmcb malloc fail");
		return NULL;
	}

	gbt27930_b_urmcb->param = param;
	return gbt27930_b_urmcb;
}

int16_t OpenChaoJi_transport_gbt27930_b_urm_free(struct OpenChaoJi_gbt27930_b_urmcb * urmcb)
{
	OpenChaoJi_os_free(urmcb);
	return 0;
}

int16_t OpenChaoJi_transport_gbt27930_b_urm_init(struct OpenChaoJi_gbt27930_b_urmcb * urmcb)
{
	if (urmcb == NULL){
		LOG_CRIT("transport urm is null");
		return -1;
	}
	urmcb->sm_recved_flag = 0;

	return 0;
}

int16_t OpenChaoJi_transport_gbt27930_b_urm_bind(struct OpenChaoJi_gbt27930_b_urmcb * urmcb, int tag, uint8_t src_addr, uint8_t dest_addr,
																int (* can_send_func)(void * param, const struct can_pdu * send_pdu),
																int (* can_recv_func)(void * param, struct can_pdu * recv_pdu))
{
	if (urmcb == NULL){
		LOG_CRIT("transport urmcb is null");
		return -1;
	}

	if (can_send_func == NULL || can_recv_func == NULL){
		LOG_CRIT("urm_bind can_send_func can_recv_func is null");
		return -1;
	}

	urmcb->tag = tag;
	urmcb->src_addr = src_addr;
	urmcb->dest_addr = dest_addr;
	urmcb->can_output_func = can_send_func;
	urmcb->can_input_func = can_recv_func;

	return 0;
}

struct OpenChaoJi_gbt27930_b_rmcb * OpenChaoJi_transport_gbt27930_b_rm_new(void * param)
{
	struct OpenChaoJi_gbt27930_b_rmcb * gbt27930_b_rmcb = NULL;
	gbt27930_b_rmcb = (struct OpenChaoJi_gbt27930_b_rmcb *)OpenChaoJi_os_malloc(sizeof(struct OpenChaoJi_gbt27930_b_rmcb));
	if (gbt27930_b_rmcb == NULL)
	{
		LOG_CRIT("transport rmcb malloc fail");
		return NULL;
	}
	gbt27930_b_rmcb->param = param;
	return gbt27930_b_rmcb;
}

int16_t OpenChaoJi_transport_gbt27930_b_rm_free(struct OpenChaoJi_gbt27930_b_rmcb * rmcb)
{
	OpenChaoJi_os_free(rmcb);

	return 0;
}

int16_t OpenChaoJi_transport_gbt27930_b_rm_init(struct OpenChaoJi_gbt27930_b_rmcb * rmcb)
{
	if (rmcb == NULL){
		LOG_CRIT("transport rmcb is null");
		return -1;
	}

	//需要确认短消息参数初始化
	rmcb->sm_send_cycle_intvl_ms = 50;
	rmcb->sm_send_max_intvl_ms = 1000;
	rmcb->sm_send_state = RSM_S0_IDLE;
	rmcb->sm_recved_flag = 0;
	rmcb->sm_send_abort = 0;

	//需要确认长消息参数初始化
	rmcb->lm_send_lms_t1_intvl_ms = 8;
	rmcb->lm_send_lms_t2_intvl_ms = 100;
	rmcb->lm_send_lms_t3_intvl_ms = 10000;
	rmcb->lm_send_active_abort = 0;
	rmcb->lm_send_state = LM_SEND_IDLE;
	rmcb->lm_send_buf = NULL;


	rmcb->lm_recv_lms_t2_intvl_ms = 100;
	rmcb->lm_recv_lms_t3_intvl_ms = 10000;
	rmcb->lm_recved_flag = 0;
	rmcb->lm_recv_state = LM_RECV_S0_IDLE;
	rmcb->lm_recv_buf = NULL;

	return 0;
}

int16_t OpenChaoJi_transport_gbt27930_b_rm_bind(struct OpenChaoJi_gbt27930_b_rmcb * rmcb, int tag, uint8_t src_addr, uint8_t dest_addr,
																int (* can_send_func)(void * param, const struct can_pdu * send_pdu),
																int (* can_recv_func)(void * param, struct can_pdu * recv_pdu))
{
	if (rmcb == NULL){
		LOG_CRIT("transport rmcb is null");
		return -1;
	}

	if (can_send_func == NULL || can_recv_func == NULL){
		LOG_CRIT("rm_bind can_send_func can_recv_func is null");
		return -1;
	}

	rmcb->tag = tag;
	rmcb->src_addr = src_addr;
	rmcb->dest_addr = dest_addr;
	rmcb->can_output_func = can_send_func;
	rmcb->can_input_func = can_recv_func;

	return 0;
}


/*
* @brief: gbt27930 B类系统可靠短消息传输中止，主要针对接收和发送
* @param {OpenChaoJi_gbt27930_b_rmcb *} rmcb 可靠消息的消息体指针，包含必要的环境信息。
* @return {*}成功返回0，失败返回-1。
*/
int16_t OpenChaoJi_transport_gbt27930_b_rsm_shutdown(struct OpenChaoJi_gbt27930_b_rmcb * rmcb)
{
	if (rmcb == NULL){
		LOG_CRIT("transport rmcb is null");
		return -1;
	}

	rmcb->sm_send_abort = 1;
	OpenChaoJi_transport_gbt27930_b_rsm_send_process(rmcb);
	rmcb->sm_send_abort = 0;

	//运行一次使状态机从END跳到IDLE
	OpenChaoJi_transport_gbt27930_b_rsm_send_process(rmcb);

	return 0;
}

//关闭发送
/*
* @brief: gbt27930 B类系统可靠长消息发送主动中止关闭
* @param {OpenChaoJi_gbt27930_b_rmcb *} rmcb 可靠消息的消息体指针，包含必要的环境信息。
* @return {*}成功返回0，失败返回-1。
*/
int16_t OpenChaoJi_transport_gbt27930_b_rlm_shutdown_wr(struct OpenChaoJi_gbt27930_b_rmcb * rmcb)
{
	if (rmcb == NULL){
		LOG_CRIT("transport rmcb is null");
		return -1;
	}
	//关闭发送端，不再发送
	rmcb->lm_send_active_abort = 1;
	OpenChaoJi_transport_gbt27930_b_rlm_send_process(NULL, rmcb);
	rmcb->lm_send_active_abort = 0;
	//运行一次使状态机从END跳到IDLE
	OpenChaoJi_transport_gbt27930_b_rlm_send_process(NULL, rmcb);

	return 0;
}

//关闭接收
/*
* @brief: gbt27930 B类系统可靠长消息接收主动中止关闭
* @param {OpenChaoJi_gbt27930_b_rmcb *} rmcb 可靠消息的消息体指针，包含必要的环境信息。
* @return {*}成功返回0，失败返回-1。
*/
int16_t OpenChaoJi_transport_gbt27930_b_rlm_shutdown_rd(struct OpenChaoJi_gbt27930_b_rmcb * rmcb)
{
	if (rmcb == NULL){
		LOG_CRIT("transport rmcb is null");
		return -1;
	}
	//关闭接收端，不再接收
	rmcb->lm_recv_active_abort = 1;
	OpenChaoJi_transport_gbt27930_b_rlm_recv_process(NULL, rmcb);
	rmcb->lm_recv_active_abort = 0;
	//运行一次使状态机从END跳到IDLE
	OpenChaoJi_transport_gbt27930_b_rlm_recv_process(NULL, rmcb);

	return 0;
}

#endif
